package com.jming.jike.service.front.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.jming.jike.common.BusinessException;
import com.jming.jike.config.MybatisPlusConfig;
import com.jming.jike.dto.front.AddressBookDTO;
import com.jming.jike.entity.AddressBook;
import com.jming.jike.entity.Region;
import com.jming.jike.mapper.AddressBookMapper;
import com.jming.jike.mapper.RegionMapper;
import com.jming.jike.service.front.AddressBookService;
import com.jming.jike.util.CopyBeanUtils;
import com.jming.jike.vo.TreeNode;
import com.jming.jike.vo.front.AddressBookVO;
import com.jming.jike.vo.front.RegionVO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 地址管理(AddressBook)表服务实现类
 *
 * @author makejava
 * @since 2022-04-16 02:02:51
 */
@Service
public class AddressBookServiceImpl implements AddressBookService {

    @Resource
    private AddressBookMapper addressBookMapper;

    @Resource
    private RegionMapper regionMapper;

    @Resource
    private MybatisPlusConfig mybatisPlusConfig;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean insert(AddressBookDTO addressBookDTO) {

        // 当前用户id
        Long operId = mybatisPlusConfig.getOperId();

        // 查询当前用户的地址数量 如果大于等于5 则不可新增
        Long count = addressBookMapper.selectCount(Wrappers.<AddressBook>lambdaQuery()
                .eq(AddressBook::getUserId, operId)
                .eq(AddressBook::getIsDeleted, 0));
        if (count >= 5L) {

            throw new BusinessException("地址数最多为5个!");
        }

        // 如果该新增的地址是默认地址 修改其他默认地址为非默认地址
        if (Integer.valueOf(1).equals(addressBookDTO.getIsDefault())) {

            addressBookMapper.update(null, Wrappers.<AddressBook>lambdaUpdate()
                    .eq(AddressBook::getUserId, operId).eq(AddressBook::getIsDefault, 1)
                    .set(AddressBook::getIsDefault, 0));
        }

        // 添加地址
        AddressBook addressBook = CopyBeanUtils.copyBean(addressBookDTO, new AddressBook());
        addressBook.setUserId(operId);

        // 插入数据 返回结果
        return addressBookMapper.insert(addressBook) > 0;
    }

    @Override
    public Boolean update(AddressBookDTO addressBookDTO) {

        // 修改地址并返回结果
        return addressBookMapper.updateById(CopyBeanUtils.copyBean(addressBookDTO, new AddressBook())) > 0;
    }

    @Override
    public Boolean delete(Long id) {

        // 删除地址并返回详情信息
        return addressBookMapper.updateById(AddressBook.builder().id(id).isDeleted(1).build()) > 0;
    }

    @Override
    public List<AddressBookVO> queryList() {

        // 查询地址列表并返回
        return CopyBeanUtils.copyBeanList(addressBookMapper.selectList(Wrappers.<AddressBook>lambdaQuery()
                .eq(AddressBook::getUserId, mybatisPlusConfig.getOperId())
                .eq(AddressBook::getIsDeleted, 0)
                .orderByDesc(AddressBook::getIsDefault)
                .orderByDesc(AddressBook::getId)), AddressBookVO.class);
    }

    @Override
    public AddressBookVO addressBookDetail(Long id) {

        // 查询地址信息并返回
        return CopyBeanUtils.copyBean(addressBookMapper.selectById(id), new AddressBookVO());
    }


    @Override
    public List<TreeNode<RegionVO>> getRegionTree() {

        List<Region> regionList = regionMapper.selectList(Wrappers.lambdaQuery());
        return this.builderTree(0, regionList);
    }

    /**
     * 将列表生成树结构
     *
     * @param pid
     * @param regionList
     * @return List<TreeNode < RegionVO>>
     * @Author jinming.zhang
     * @Date 2022/5/18
     */
    private List<TreeNode<RegionVO>> builderTree(Integer pid, List<Region> regionList) {

        return regionList.stream().filter(reg -> reg.getPid() != null && reg.getPid().equals(pid))
                .map(child -> {
                    TreeNode<RegionVO> node = new TreeNode<>();
                    node.setNode(CopyBeanUtils.copyBean(child, new RegionVO()));
                    node.setChildren(this.builderTree(child.getId(), regionList));
                    return node;
                }).collect(Collectors.toList());
    }
}
